package GUI;

import GUITOOl.*;
import Service.SendFile;
import Service.SendMsg;
import Service.ShowChatHistory;
import Utils.*;
import Service.SaveChatHistory;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.*;
import java.awt.event.*;
import java.io.*;
import java.util.List;

/**
 * The type Chat frame.
 *
 * @author dzr, wyc, zry
 * @version 1.0
 */
public class ChatFrame extends JFrame{
    /**
     * The constant MSG_TEXT.
     */
    public static final int MSG_TEXT = 0;
    /**
     * The constant MSG_IMG.
     */
    public static final int MSG_IMG = 1;
    /**
     * The constant MSG_FILE.
     */
    public static final int MSG_FILE = 2;
    /**
     * The constant MAX_SIZE.
     */
    public static final long MAX_SIZE = 2097152L;
    /**
     * The Sender's name.
     */
    String s_name;
    /**
     * The Sender's uid.
     */
    int s_uid;
    /**
     * The Receiver's name.
     */
    String r_name;
    /**
     * The Receiver's uid.
     */
    int r_uid;
    /**
     * The Msg area.
     */
    JPanel msg_area;
    /**
     * The Input text.
     */
    JTextArea input_text;
    /**
     * The Main content's Panel.
     */
    JScrollPane jp;
    /**
     * To Send msg.
     */
    JButton sendMsg;
    /**
     * To Send file.
     */
    JButton sendFile;
    /**
     * To Show chat history.
     */
    JButton showChatHistory;
    /**
     * The Panel n.
     */
    JPanel panel_N=new JPanel();
    /**
     * The Panel s.
     */
    JPanel panel_S=new JPanel();
    /**
     * The File of Friend chat history.
     */
    File friendChatHistory;

    /**
     * Instantiates a new Chat frame.
     *
     * @param s_name the s name
     * @param s_uid  the s uid
     * @param r_name the r name
     * @param r_uid  the r uid
     */
    public ChatFrame(String s_name, int s_uid, String r_name, int r_uid){
        this.s_name = s_name;
        this.s_uid = s_uid;
        this.r_name = r_name;
        this.r_uid = r_uid;
        init();
    }

    /**
     * Init ChatFrame.
     */
    public void init(){
        setTitle("chatting with "+r_name);
        Image frameImage=ImageIconUtils.getRawPicture("picture.png").getImage();
        setIconImage(frameImage);
        MyLineBorder myLineBorder=new MyLineBorder(new Color(192, 192, 192), 1 , true);
        Color bgColor = new Color(255, 255, 255);
        setResizable(false);
        setLocationRelativeTo(null);
        getContentPane().setBackground(bgColor);
        setLayout(new FlowLayout());
        setSize(600,600);
        setLocation(GetWindowsSize.getWindowsSize().width / 2 - this.getWidth() / 2, GetWindowsSize.getWindowsSize().height / 2 - this.getHeight() / 2);
        BorderLayout border_layout=new BorderLayout();
        setLayout(border_layout);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        friendChatHistory = new File(ThreadManage.getInstance().getClientThread(s_uid).getRootHistory().getPath() + File.separator + r_uid + ".txt");
        if(! friendChatHistory.exists()){
            try {
                friendChatHistory.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        msg_area=new JPanel();
        msg_area.setBorder(myLineBorder);
        msg_area.setBounds(555,555,600,350);
        msg_area.setBackground(bgColor);
        msg_area.setLayout(new BoxLayout(msg_area,BoxLayout.Y_AXIS));

        input_text = new JTextArea(3, 30);
        input_text.setBorder(myLineBorder);
        input_text.setLineWrap(true);
        sendMsg = new MyButton("发送",1);
        Box box_bottom;
        box_bottom=Box.createHorizontalBox();
        box_bottom.add(input_text);
        box_bottom.add(Box.createHorizontalStrut(5));

        panel_N.setLayout(null);
        panel_N.setPreferredSize(new Dimension(0, 140));
        panel_N.setBackground(bgColor);
        ImageIcon image= ImageIconUtils.getRawPicture("chat_top1.png");
        JLabel background=new JLabel(image);
        background.setBounds(0,0,600,150);
        panel_N.add(background);

        add(panel_N,BorderLayout.NORTH);


        sendMsg.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                sendMsg();
            }
        });
            input_text.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if(e.getKeyChar() ==KeyEvent.VK_ENTER) {
                    sendMsg();
                }
            }
        });

        jp=new JScrollPane(msg_area,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        jp.setBorder(null);
        jp.getVerticalScrollBar().setUI(new MyScrollBarUI());
        jp.getHorizontalScrollBar().setUI(new MyScrollBarUI());
        jp.setBounds(555,555,600,350);
        jp.setBackground(bgColor);
        add(jp,BorderLayout.CENTER);

        sendFile = new MyButton("文件传输",1);
        DropTargetListener listener = new DropTargetListenerImpl(input_text);
        DropTarget dropTarget = new DropTarget(input_text, DnDConstants.ACTION_MOVE, listener);

        sendFile = new MyButton("文件传输");
        sendFile.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser jfc = new JFileChooser();
                int status = jfc.showOpenDialog(ChatFrame.this);
                if(status == JFileChooser.APPROVE_OPTION){
                    try {
                        File file = jfc.getSelectedFile();
                        int fileType = MSG_FILE;
                        if (IsImage.isImage(file)){
                            fileType = MSG_IMG;
                        }
                        showMsg(fileType, s_uid, s_name, Date.getCurTime(), file.getPath());
                        SendFile.sendFile(fileType, file.getPath(), s_uid, r_uid);
                    }catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
            }
        });
        showChatHistory = new MyButton("查看历史消息",1);
        showChatHistory.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    ShowChatHistory.showChatHistory(s_uid, s_name, r_uid, r_name, ChatFrame.this, friendChatHistory);
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                }
            }
        });
        box_bottom.add(sendMsg);
        box_bottom.add(Box.createHorizontalStrut(5));
        box_bottom.add(sendFile);
        box_bottom.add(Box.createHorizontalStrut(5));
        box_bottom.add(showChatHistory);
        panel_S.add(box_bottom);
        panel_S.setBackground(bgColor);
        add(panel_S,BorderLayout.SOUTH);
        setVisible(true);
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                ChatManage.closeChat(r_uid);
                ChatFrame.this.dispose();
            }
        });
    }

    /**
     * Send msg.
     */
    public void sendMsg(){
        if(!input_text.getText().isEmpty()){
            int msgType = MSG_TEXT;
            String content = input_text.getText().replace('\n', '\0');
            String time = Date.getCurTime();

            File file = new File(content);
            if(file.exists()){
                if (file.length() > MAX_SIZE){
                    msgType = -1;
                    new showMessageFrame("文件/图片过大，请重新选择");
                }else {
                    if(IsImage.isImage(file)){
                        msgType = MSG_IMG;
                    }else{
                        msgType = MSG_FILE;
                    }
                }
            }
            input_text.setText("");
            switch (msgType){
                case MSG_TEXT:{
                    try {
                        showMsg(MSG_TEXT, s_uid, s_name, time, content);
                        SendMsg.sendMsg(s_uid, r_uid, time, content);
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    break;
                }
                case MSG_IMG:{
                    try {
                        showMsg(MSG_IMG, s_uid, s_name, time, content);
                        SendFile.sendFile(MSG_IMG, content, s_uid, r_uid);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                }
                case MSG_FILE:{
                    try {
                        showMsg(MSG_FILE,s_uid, s_name, time, content);
                        SendFile.sendFile(MSG_FILE, content, s_uid, r_uid);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                }
                default:
                    break;
            }
        }else{
            new showMessageFrame("发送内容不能为空");
            System.out.println("输入不能为空");
        }
    }

    /**
     * Show msg.
     *
     * @param msgType the msg type
     * @param name    the name
     * @param time    the time
     * @param content the content
     */
    public void showMsg(int msgType, int s_uid, String name, String time, String content){

        Color bgColor=new Color(255, 255, 255);
        MyLineBorder myLineBorder1 = new MyLineBorder(bgColor, 1 , true);
        MyLineBorder myLineBorder2 = new MyLineBorder(new Color(39, 121, 181),1,true);
        String title = time + "  " + name + "(" + s_uid + ")";
        MyTextArea myTextArea = new MyTextArea(title);
        switch (msgType){
            case MSG_TEXT:{
                JLabel label1=new JLabel();
                JLabel label2=new JLabel();
                myTextArea.setSize(new Dimension(10,0));
                myTextArea.append("\n    ");
                myTextArea.append(content);
                myTextArea.setLineWrap(true);
                JPanel panel1;
                JPanel panel2;
                JPanel panel3;
                if(s_uid == this.s_uid){
                    label1.setBorder(myLineBorder1);
                    label2.setBorder(myLineBorder2);
                    panel1=new JPanel(new FlowLayout(FlowLayout.TRAILING));
                    panel2=new JPanel(new FlowLayout(FlowLayout.TRAILING));
                    panel3=new JPanel(new FlowLayout(FlowLayout.TRAILING));
                }
                else {
                    label1.setBorder(myLineBorder1);
                    label2.setBorder(myLineBorder2);
                    panel1=new JPanel(new FlowLayout(FlowLayout.LEADING));
                    panel2=new JPanel(new FlowLayout(FlowLayout.LEADING));
                    panel3=new JPanel(new FlowLayout(FlowLayout.LEADING));
                }
                label1.setText(title);
                label1.setFont(new Font("宋体",1,12));
                label2.setSize(180,0);
                try {
                    Html2Text.JlabelSetText(label2,content);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                label2.setFont(new Font("微软雅黑",1,14));
                panel1.add(label1);
                panel2.add(label2);
                panel3.setBorder(myLineBorder2);
                panel3.setBackground(bgColor);
                panel3.add(myTextArea);
                panel1.setBackground(bgColor);
                panel2.setBackground(bgColor);
                msg_area.add(panel1);
                msg_area.add(panel2);
                msg_area.revalidate();
                JScrollBar verticalScrollBar = jp.getVerticalScrollBar();
                SwingUtilities.invokeLater(() -> verticalScrollBar.setValue(verticalScrollBar.getMaximum()));
                break;
            }
            case MSG_IMG:{
                JLabel label1=new JLabel();
                label1.setText(title);
                JLabel label2=new JLabel();
                JPanel panel1;
                JPanel panel2;
                if(s_uid == this.s_uid){
                    label1.setBorder(myLineBorder1);
                    label2.setBorder(myLineBorder2);
                    panel1=new JPanel(new FlowLayout(FlowLayout.TRAILING));
                    panel2=new JPanel(new FlowLayout(FlowLayout.TRAILING));
                }
                else {
                    label1.setBorder(myLineBorder1);
                    label2.setBorder(myLineBorder2);
                    panel1=new JPanel(new FlowLayout(FlowLayout.LEADING));
                    panel2=new JPanel(new FlowLayout(FlowLayout.LEADING));
                }
                label1.setFont(new Font("宋体",1,12));
                panel1.add(label1);
                label2=new MyImageLabel(content,this);
                label2.setBorder(myLineBorder2);
                panel2.add(label2);
                panel1.setBackground(bgColor);
                panel2.setBackground(bgColor);
                msg_area.add(panel1);
                msg_area.add(panel2);
                msg_area.revalidate();
                JScrollBar verticalScrollBar = jp.getVerticalScrollBar();
                SwingUtilities.invokeLater(() -> verticalScrollBar.setValue(verticalScrollBar.getMaximum()));
                break;
            }
            case MSG_FILE:{
                JLabel label1=new JLabel();
                label1.setText(title);
                JLabel label2=new JLabel();
                JPanel panel1;
                JPanel panel2;
                if(s_uid == this.s_uid){
                    label1.setBorder(myLineBorder1);
                    label2.setBorder(myLineBorder2);
                    panel1=new JPanel(new FlowLayout(FlowLayout.TRAILING));
                    panel2=new JPanel(new FlowLayout(FlowLayout.TRAILING));
                }
                else {
                    label1.setBorder(myLineBorder1);
                    label2.setBorder(myLineBorder2);
                    panel1=new JPanel(new FlowLayout(FlowLayout.LEADING));
                    panel2=new JPanel(new FlowLayout(FlowLayout.LEADING));
                }
                label2 = new MyFileLable(content);
                label2.setBorder(myLineBorder2);
                label1.setFont(new Font("宋体",1,12));
                panel1.add(label1);
                panel2.add(label2);
                panel1.setBackground(bgColor);
                panel2.setBackground(bgColor);
                msg_area.add(panel1);
                msg_area.add(panel2);
                msg_area.revalidate();
                JScrollBar verticalScrollBar = jp.getVerticalScrollBar();
                SwingUtilities.invokeLater(() -> verticalScrollBar.setValue(verticalScrollBar.getMaximum()));
                break;
            }
            default:
                break;
        }

        try {
            SaveChatHistory.saveChatHistory(title, content, friendChatHistory);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Close Chat Frame.
     */
    public void close(){
        ChatManage.chatFrames.remove(r_uid);
        this.dispose();
    }

    /**
     * The type Drop target listener.
     *
     * @author dzr
     * @version 1.0
     */
    static class DropTargetListenerImpl implements DropTargetListener{

        private final JTextArea jTextArea;

        /**
         * Instantiates a new Drop target listener.
         *
         * @param jTextArea the jtextarea
         */
        public DropTargetListenerImpl(JTextArea jTextArea) {
            this.jTextArea= jTextArea;
        }

        @Override
        public void dragEnter(DropTargetDragEvent dtde) {

        }

        @Override
        public void dragOver(DropTargetDragEvent dtde) {

        }

        @Override
        public void dropActionChanged(DropTargetDragEvent dtde) {

        }

        @Override
        public void dragExit(DropTargetEvent dte) {

        }

        @Override
        public void drop(DropTargetDropEvent dtde) {
            try {
                if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                    dtde.acceptDrop(DnDConstants.ACTION_MOVE);

                   List<File> files = (List<File>) dtde.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
                    if (files.size() == 1) {
                        File file = files.get(0);
                        jTextArea.setText(file.getPath());
                    }
                    dtde.dropComplete(true);
                }else{
                    dtde.rejectDrop();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}